package tableaux.backjumping;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.Map;

import utils.exception.BackjumpingNoDepSetException;

import entities.Individual;
import entities.concept.Concept;

/**
 * A dependency set has the information: which concept in which node's label
 * depends on which branching
 * 
 * @author j55wu
 * 
 */
public class DependencyImpMax {

	private static Map<Individual, Map<Concept, Integer>> deps = new HashMap<Individual, Map<Concept, Integer>>();

	public static void clearDependencies() {
		deps.clear();
	}

	public static void testMethodFindConceptDep(Concept c) {
		for (Map<Concept, Integer> v : deps.values()) {
			if (v.containsKey(c)) {
				System.out.println(v.get(c));
			}
		}
	}

	public static void addDep(Individual ind, Concept c, Set<Integer> is) {
		if (is.size() == 1) {
			addDep(ind, c, is.iterator().next());
			return;
		}
		List<Integer> list = new ArrayList<Integer>(is);
		Collections.sort(list);
		Integer max = list.get(list.size() - 1);
		addDep(ind, c, max);
	}

	/**
	 * Change only if the supplied dep value is GREATER than the stored value
	 * 
	 * @param ind
	 * @param c
	 * @param is
	 */
	public static void addDep(Individual ind, Concept c, Integer is) {
		Map<Concept, Integer> ci;
		if (deps.containsKey(ind)) {
			if (deps.get(ind).containsKey(c)) {
				if (deps.get(ind).get(c) < is) {
					deps.get(ind).put(c, is);
				}
			} else {
				deps.get(ind).put(c, is);
			}
		} else {
			ci = new HashMap<Concept, Integer>();
			ci.put(c, is);
			deps.put(ind, ci);
		}
	}

	public static Integer getDepOfConcept(Individual ind, Concept c) {
		if (deps.containsKey(ind)) {
			if (deps.get(ind).containsKey(c)) {
				return deps.get(ind).get(c);
			}
		}
		return 0;
	}

	public static boolean dependOnBranch(Individual ind, Concept c, Integer i) {
		if (deps.containsKey(ind) && deps.get(ind).containsKey(c)
				&& deps.get(ind).get(c) == i) {
			return true;
		}
		return false;
	}

	public static Set<Integer> findClashBranch(Individual ind, Concept c1,
			Concept c2) throws BackjumpingNoDepSetException {
		Set<Integer> bs = new HashSet<Integer>();
		Integer l1 = getDepOfConcept(ind, c1);
		Integer l2 = getDepOfConcept(ind, c2);
		if (l1 >= 0) {
			bs.add(l1);
		} else {
			throw new BackjumpingNoDepSetException("No dep set found for " + c1);
		}
		if (l2 >= 0) {
			bs.add(l2);
		} else {
			throw new BackjumpingNoDepSetException("No dep set found for " + c2);
		}
		return bs;
	}

}
